<template>
  <Page :title="navTitle">
    <template #navBarCustom>
      <div class="flex items-center navBox">
        <div class="back" @click="back">
          <img class="icon" src="static/icons/back.png" mode="" />
          <span style="color: #fff">{{ navTitle }}</span>
        </div>
        <div class="nav-bar-btns flex" style="margin-left: auto">
          <div class="item flex items-center" @click="isShowSetting = true">
            <img class="icon mt-2px mr-4px" src="static/icons/setting.png" mode="" />
            <span class="name text-white">设置</span>
          </div>
        </div>
      </div>
    </template>
    <template #content>
      <div class="w-full h-full px-20px pt-20px box-border flex flex-col">
        <div
          class="container w-full h-full flex-1 flex flex-col bg-white p-20px box-border overflow-hidden"
        >
          <div ref="scroll" class="w-full h-full overflow-scroll">
            <!-- 听后选择 -->
            <Choose ref="choose" v-if="questionType === 'choose'" />
            <!-- 听后回答 -->
            <Dialogue ref="dialogue" v-if="questionType === 'dialogue'" />
            <!-- 短文朗读 -->
            <Read ref="read" v-if="questionType === 'read'" />
            <!-- 听后记录 -->
            <Fill ref="read" v-if="questionType === 'fill'" />
            <!-- 听后转述 -->
            <Picture ref="read" v-if="questionType === 'picture'" />
          </div>
        </div>
        <!-- 操作区 -->
        <div class="operate-wrap flex items-center py-30px">
          <img
            class="icon mr-10px"
            :src="isPause ? 'static/icons/play.png' : 'static/icons/playing.png'"
            mode=""
            @click="isPause ? controller.setStatus('normal') : controller.setStatus('pause')"
          />
          <div class="tips text-333">
            <span>{{ operateTips }}</span>
          </div>
        </div>
        <!-- 设置 -->
        <div class="setting-wrap flex flex-col justify-center" v-show="isShowSetting">
          <div class="setting bg-white px-30px py-40px relative flex flex-col">
            <div
              class="controller py-20px relative w-full flex justify-center items-center text-white"
            >
              <img
                class="close absolute"
                src="static/icons/close.png"
                mode=""
                @click="isShowSetting = false"
              />
              <img
                class="prev-stage"
                src="static/icons/prev-stage.png"
                mode=""
                @click="toPrevStage()"
              />
              <img
                class="current-status mx-40px"
                :src="isPause ? 'static/icons/play.png' : 'static/icons/playing.png'"
                mode=""
                @click="isPause ? controller.setStatus('normal') : controller.setStatus('pause')"
              />
              <img
                class="next-stage"
                src="static/icons/next-stage.png"
                mode=""
                @click="toNextStage()"
              />
            </div>
            <div class="main text-333 pt-20px">
              <div class="operate-tips flex justify-center"
                ><span class="text-left">{{ operateTips }}</span></div
              >
              <div class="py-30px flex justify-between items-center">
                <div style="width: 1.19rem; height: 0; border: 0.01rem solid #eeeeee"></div>
                <div style="font-size: 0.18rem">语速调节</div>
                <div style="width: 1.19rem; height: 0; border: 0.01rem solid #eeeeee"></div>
              </div>
              <div class="speed flex justify-between">
                <div
                  class="btn flex-center"
                  :class="controller.speed < 1 ? 'active' : ''"
                  @click="controller.changeSpeed('turnDown')"
                  >放慢</div
                >
                <div
                  class="btn flex-center"
                  :class="controller.speed === 1 ? 'active' : ''"
                  @click="controller.changeSpeed('normal')"
                  >正常</div
                >
                <div
                  class="btn flex-center"
                  :class="controller.speed > 1 ? 'active' : ''"
                  @click="controller.changeSpeed('turnUp')"
                  >加快</div
                >
              </div>
            </div>
          </div>
        </div>
        <!-- 退出练习弹窗 -->
        <div class="quit-practice-dialog-wrap" v-show="isShowQuitPracticeDialog">
          <div class="quit-practice-dialog bg-white px-24px py-30px relative flex flex-col">
            <div class="header relative w-full flex justify-center items-center text-white">
              <img
                class="close absolute"
                src="static/icons/close.png"
                mode=""
                @click="isShowQuitPracticeDialog = false"
              />
              <div class="title font-medium text-262A30">提示</div>
            </div>
            <div class="main text-A3A3A3 py-30px flex-center flex-1">
              已练习{{ practiceCount }}道题目，确认退出本次练习？
            </div>
            <div class="footer flex justify-center">
              <CustomButton class="block" style="width: 2rem" @click="quitPractice"
                >确认</CustomButton
              >
            </div>
          </div>
        </div>
      </div>
    </template>
  </Page>
</template>

<script>
import { mapState } from 'vuex'
import Page from '@/components/page/newPage'
import CustomButton from '@/components/button'
import Controller from './controller'
import Choose from './components/choose'
import Dialogue from './components/dialogue'
import Read from './components/read'
import Fill from './components/fill'
import Picture from './components/picture'
import { englishCheckAnswerApi, quitPracticeApi } from '@/api/exercise'
import { checkStudyClockinApi, updateTodayStatusApi } from '@/api/daily-attendance'
import { debounce } from '@/utils'

export default {
  components: { Page, CustomButton, Choose, Dialogue, Read, Fill, Picture },
  provide() {
    return {
      globalData: this.$data
    }
  },
  beforeRouteLeave(to, from, next) {
    if (this.canBack) {
      next()
    } else {
      this.isShowQuitPracticeDialog = true
      window.history.pushState(null, null, '/#/pages/exercise/practice/english/index')
    }
  },
  data() {
    return {
      studyClockinDetailList: [], // 所有未结束的每日打卡任务详情列表
      studyClockinDetailIds: [], // 所有未结束的每日打卡任务详情id列表
      subjectId: '',
      isShowQuitPracticeDialog: false,
      canBack: false,
      // 累计时间
      cumulativeTime: {
        vm: this._self,
        timeout: null,
        // 单位：秒
        value: 0,
        // 累加
        run: function () {
          this.timeout = setTimeout(() => {
            this.value++
            this.run()
          }, 1000)
        },
        reset: function () {
          clearTimeout(this.timeout)
          this.value = 0
        }
      },
      isShowSetting: false,
      controller: new Controller(),
      toPrevStage: debounce(() => {
        this.controller.toPrevStage()
      }, 300),
      toNextStage: debounce(() => {
        this.controller.toNextStage()
      }, 300)
    }
  },
  computed: {
    ...mapState(['exerciseCenter']),
    currentPractice() {
      return this.exerciseCenter.currentPractice
    },
    questionIndex() {
      const { questionIndex } = this.exerciseCenter.currentPractice

      return questionIndex
    },
    questions() {
      const { questions } = this.exerciseCenter.currentPractice

      return questions
    },
    currentQuestion() {
      const { questions, questionIndex } = this.currentPractice

      if (!questions || questions.length === 0) return {}

      return questions[questionIndex]
    },
    questionType() {
      const { stem = {} } = this.currentQuestion
      const { structure_type = '' } = stem

      return structure_type.replace('collector.', '')
    },
    practiceCount() {
      const { questions } = this.exerciseCenter.currentPractice

      return questions.length - 1
    },
    navTitle() {
      const { stem = {} } = this.currentQuestion
      const { structure_type = '' } = stem

      switch (structure_type) {
        case 'collector.choose':
          return `听后选择`
        case 'collector.dialogue':
          return `听后回答`
        case 'collector.read':
          return `短文朗读`
        case 'collector.fill':
          return `听后记录`
        case 'collector.picture':
          return `听后转述`
        default:
          return ''
      }
    },
    operateTips() {
      const { operateTips } = this.controller
      return operateTips
    },
    isPause() {
      if (this.controller.getStatus() === 'pause') {
        return true
      } else {
        return false
      }
    }
  },
  watch: {
    questionIndex(newVal, oldVal) {
      if (oldVal === -1) return

      const {
        stem: { old_structure_type }
      } = this.questions[oldVal]
      const {
        stem: { new_structure_type }
      } = this.questions[newVal]

      // 题型相同，跳过题型说明
      if (new_structure_type === old_structure_type) {
        let refComp =
          this.$refs.choose ||
          this.$refs.dialogue ||
          this.$refs.read ||
          this.$refs.fill ||
          this.$refs.picture
        refComp.init(1)
      } else {
        refComp.init(0)
      }
    },
    currentPractice: {
      handler(newVal, oldVal) {},
      immediate: false,
      deep: true
    },
    isPause(newVal) {
      let refComp =
        this.$refs.choose ||
        this.$refs.dialogue ||
        this.$refs.read ||
        this.$refs.fill ||
        this.$refs.picture

      if (newVal) {
        refComp.$emit('pause')
      } else {
        refComp.$emit('resume')
      }
    }
  },
  created() {
    this.init()
  },
  mounted() {
    this.cumulativeTime.run()
    console.log(this.currentPractice)
  },
  beforeDestroy() {
    this.cumulativeTime.reset()
    this.controller.destroy()
  },
  methods: {
    back() {
     this.$router.back()
    },
    async init() {
      // 查询是否存在打卡任务
      const { record } = this.exerciseCenter.currentPractice
      const isRecommend = !!record.questionId // true => 举一反三 false => 习题中心
      if (isRecommend) {
        const { subjectId, kpointIds } = record
        checkStudyClockinApi({
          subjectId,
          kpointIds: kpointIds.join(','),
          type: 1
        }).then(({ data }) => {
          if (Array.isArray(data)) {
            this.studyClockinDetailList = data
            this.studyClockinDetailIds = data.map((item) => item.id)
          }
        })
      } else {
        const { subjectId, kpointIds } = record
        checkStudyClockinApi({
          subjectId,
          kpointIds: kpointIds.join(','),
          type: 2
        }).then(({ data }) => {
          if (Array.isArray(data)) {
            this.studyClockinDetailList = data
            this.studyClockinDetailIds = data.map((item) => item.id)
          }
        })
      }
      // 记录学科id
      const {
        query: { subjectId = '' }
      } = this.$route

      this.subjectId = subjectId
      this.controller.onSubmit = this.submit
    },
    async submit() {
      // 不是最后一题，切换下一题
      if (this.questionIndex < this.questions.length - 1) {
        this.currentPractice.questionIndex++
        return
      }

      const { record } = this.currentPractice
      const { id: practiceId } = record
      const {
        questionId,
        stem,
        typeId,
        typename: questionSoureType,
        localStudentAnswer: { studentAnswer }
      } = this.currentQuestion

      let answerScoreable = 0

      try {
        const loading = this.$loading({
          lock: true,
          text: '提交答案...',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.5)'
        })
        // 一分钟内上传不成功关闭loading弹窗
        const timer = setTimeout(() => {
          loading.close()
        }, 60000)

        const { structure_type = '' } = stem

        switch (structure_type) {
          case 'collector.choose':
            answerScoreable = 1
            const { questionIds, kpointPracticeIds } = this.currentQuestion

            // 打卡任务练习时长
            let studentQuestionDuration = 0
            let questionSort = 1
            Promise.all(
              questionIds.map(async (id, index) => {
                const data = {
                  practiceId: kpointPracticeIds[index], //练习id
                  questionId: id, // 问题id
                  questionSort: questionSort++, // 题目序号
                  questionType: typeId, // 题型
                  questionSoureType,
                  answerScoreable, // 是否支持机阅
                  studentAnswer: JSON.stringify({ anSqs: studentAnswer.anSqs[index] }), // 学生作答答案
                  practiceDuration: (this.cumulativeTime.value * 1000) / 4, // 练习时间
                  amend: 0,
                  wrongQuestionBookId: 0,
                  praccticeDetailId: 0,
                  recordKnowledgeId: 0
                }

                await englishCheckAnswerApi(data)
                studentQuestionDuration += data.practiceDuration / 1000
              })
            ).then(() => {
              // 如果存在打卡任务
              const { questionId } = record
              const isRecommend = !!questionId // true => 举一反三 false => 习题中心
              if (this.studyClockinDetailIds.length > 0) {
                this.studyClockinDetailIds.forEach((id) => {
                  updateTodayStatusApi({
                    id,
                    studentQuestionDuration,
                    studentQuestionNum: 1,
                    studentQoNum: answerScoreable ? 1 : 0, // 客观题数量
                    studentQsNum: answerScoreable ? 0 : 1, // 主观题数量
                    type: isRecommend ? 1 : 2 // 1 => 举一反三 2 => 习题中心
                  })
                })
              }

              clearTimeout(timer)
              loading.close()
              this.quitPractice({
                routePath: `/pages/exercise/record/detail/english/index?id=${Array.from(
                  new Set(kpointPracticeIds)
                ).join(',')}&subjectId=${this.subjectId}`,
                routeType: 'replace'
              })
            })
            break
          default:
            const data = {
              practiceId, //练习id
              questionId, // 问题id
              questionSort: this.questionIndex + 1, // 题目序号
              questionType: typeId, // 题型
              questionSoureType,
              answerScoreable, // 是否支持机阅
              studentAnswer: JSON.stringify(studentAnswer), // 学生作答答案
              practiceDuration: this.cumulativeTime.value * 1000, // 练习时间
              amend: 0,
              wrongQuestionBookId: 0,
              praccticeDetailId: 0,
              recordKnowledgeId: 0
            }

            const { code } = await englishCheckAnswerApi(data)
            if (code === 0) {
              // 如果存在打卡任务
              const { questionId } = record
              const isRecommend = !!questionId // true => 举一反三 false => 习题中心
              if (this.studyClockinDetailIds.length > 0) {
                this.studyClockinDetailIds.forEach((id) => {
                  updateTodayStatusApi({
                    id,
                    studentQuestionDuration,
                    studentQuestionNum: 1,
                    studentQoNum: answerScoreable ? 1 : 0, // 客观题数量
                    studentQsNum: answerScoreable ? 0 : 1, // 主观题数量
                    type: isRecommend ? 1 : 2 // 1 => 举一反三 2 => 习题中心
                  })
                })
              }

              clearTimeout(timer)
              loading.close()
              this.quitPractice({
                routePath: `/pages/exercise/record/detail/english/index?id=${practiceId}&subjectId=${this.subjectId}`,
                routeType: 'replace'
              })
            }
            break
        }
      } catch (error) {
        console.log(error)
      }
    },
    async quitPractice({ routePath = '', routeType = 'back' } = {}) {
      const {
        currentPractice: {
          record: { id }
        }
      } = this.exerciseCenter

      // 加载动画
      const loading = this.$loading({
        lock: true,
        text: '保存中...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.5)'
      })
      // 一分钟内加载不成功关闭loading弹窗
      const timer = setTimeout(() => {
        loading.close()
      }, 60000)

      await quitPracticeApi({
        id
      })
      this.canBack = true

      // 关闭加载动画
      clearTimeout(timer)
      loading.close()

      switch (routeType) {
        case 'replace':
          this.$router.replace(routePath)
          break
        default:
          this.$router.back()
          break
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.navBox {
  padding: 0 20px;
  box-sizing: border-box;
}
.back {
  height: 100%;
  display: flex;
  align-items: center;
  font-size: 28px;

  .icon {
    width: 17.14px;
    height: 30px;
    margin-right: 11px;
  }
}
.nav-bar-btns {
  .item {
    height: 30px;
    .icon {
      width: 22px;
      height: 22px;
    }

    .name {
      font-size: 22px;
      line-height: 22px;
    }
  }
}

.container {
  border-radius: 16px;

  /deep/ .type-intro {
    white-space: break-spaces;
    word-break: break-all;
    font-size: 0;

    .type {
      font-size: 0.22rem;
      line-height: 0.22rem;
      font-weight: 500;
    }

    .intro {
      font-size: 0.18rem;
      line-height: 0.28rem;
    }
  }
}

.operate-wrap {
  font-size: 18px;

  .icon {
    width: 40px;
    height: 40px;
  }

  .tips {
  }
}

.setting-wrap {
  width: 100vw;
  height: 100vh;
  background: rgba($color: #000000, $alpha: 0.5);
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1999;

  .setting {
    width: 418px;
    min-height: 241px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    border-radius: 16px;
    border: 1px solid #707070;

    .controller {
      .close {
        width: 16px;
        height: 16px;
        top: -22px;
        right: -14px;
      }

      .prev-stage {
        width: 26px;
        height: 26px;
      }

      .current-status {
        width: 40px;
        height: 40px;
      }

      .next-stage {
        width: 26px;
        height: 26px;
      }
    }

    .main {
      font-size: 20px;
      line-height: 28px;

      .speed {
        font-size: 22px;
        color: #a3a3a3;
        font-weight: 400;

        .btn {
          width: 130px;
          height: 50px;
          border-radius: 25px;
          border: 1px solid #d9d9d9;

          &.active {
            border: 0.01rem solid #51c3ff;
            color: #51c3ff;
          }
        }
      }
    }
  }
}

.quit-practice-dialog-wrap {
  width: 100vw;
  height: 100vh;
  background: rgba($color: #000000, $alpha: 0.5);
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1999;

  .quit-practice-dialog {
    width: 348px;
    min-height: 158px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    border-radius: 16px;
    border: 1px solid #707070;

    .header {
      .close {
        width: 16px;
        height: 16px;
        top: -12px;
        right: -8px;
      }

      .title {
        font-size: 22px;
        line-height: 30px;
      }
    }

    .main {
      font-size: 20px;
      line-height: 28px;
    }

    .footer {
    }
  }
}
</style>
